<?php

namespace App\Customer\Model;

use App\Service\EsSearch;
use App\Web\Model\CaseFlow;
use EchoPHP\Facades\Db;
use EchoPHP\Facades\Log;
use EchoPHP\Facades\Redis;
use EchoPHP\Facades\Validation;
use RuntimeException;

class CaseModel extends Model {
    private $tablename = 'SCase';
    protected $field = 'caseid,casename,subid,projectid,salaryfrom,salaryto,area,creator,createdate,duedate,status,content';
    private $batchFields = ['status', 'listindex'];

    //caseid存储redis的有效期
    private $redisExpre = 60 * 60 * 2;

    /**
     * 获取交易公司列表
     * @param $hrUid
     * @return mixed
     */
    public function getSubCaseInfo($hrUid) {
        $returnData = [
            'sublist' => [],
            'caseids' => []
        ];
        $subData = $this->getSubList($hrUid);
        $accountId = array_column($subData, 'accountid');
        //获取caseid并存入redis
        if (!empty($accountId)) {
            $redisClient = Redis::connect('customers');
            $search['accountid'] = $accountId;
            //职位获取进行中的职位
            $search['status'] = ['01'];
            $caseData = $this->getCaseInfo('a.caseid,a.subid', $search);
            $groupBySubIdData = [];
            if (!empty($caseData)) {
                foreach ($caseData as $v) {
                    $groupBySubIdData[$v['subid']][] = $v['caseid'];
                }
                unset($caseData);
                $returnData['caseids'] = $groupBySubIdData;
                //存入缓存
                foreach ($groupBySubIdData as $key => $datum) {
                    array_unique($datum);
                    $keyName = "customersubidcaseids:hruid" . $hrUid . ":subid" . $key;
                    $redisClient->del($keyName);
                    $redisClient->sAddArray($keyName, $datum);
                    $time = $this->redisExpre;
                    $redisClient->expire($keyName, $time);
                }
            }
        }
        $returnData['sublist'] = $subData;
        return $returnData;
    }

    /**
     * 根据id获取职位列表
     * @param $caseIds
     * @param null $field
     * @return array
     */
    public function getCaseList($field, $caseIds, $rowFrom = 0, $rowTo = 0, $orderBy = '', $searchParam = []) {
        $caseIds = array_filter(explode(',', $caseIds));
        if (empty($caseIds)) {
            return null;
        }

        foreach ($caseIds as $key => $item) {
            if (!is_numeric($item)) {
                unset($caseIds[$key]);
            }
        }

        if (empty($caseIds)) {
            return null;
        }

        $var = array();
        $this->arrValueToKey($caseIds);
        $placeTag = $this->arrAppand($var, $caseIds);
        if ($placeTag == "") {
            return null;
        }

        $fields = empty($field) ? " SCase.*,CustomerSub.subname" : $field;

        $sql = 'SELECT ' . $fields . ' FROM ' . $this->tablename . ' LEFT JOIN CustomerSub ON SCase.subid=CustomerSub.subid 
        WHERE caseid IN(' . $placeTag . ') ';
        if (isset($searchParam['casename']) && !empty($searchParam['casename'])) {
            $sql .= " AND caseshowname like ? ";
            $var[] = '%' . $searchParam['casename'] . "%";
        }

        if (isset($searchParam['status']) && !empty($searchParam['status'])) {
            $sql .= " AND  `status` = ? ";
            $var[] = $searchParam['status'];
        }

        $sql .= empty($orderBy) ? ' order by subname,casename,caseid ' : (' ORDER BY ' . $orderBy);

        return Db::select($sql, $var, $rowFrom, $rowTo);
    }

    /**
     * 根据id获取职位列表总数
     * @param $caseIds
     * @param null $field
     * @return array
     */
    public function getCaseListCount($caseIds) {
        $caseIds = array_filter(explode(',', $caseIds));
        if (empty($caseIds)) {
            return 0;
        }

        foreach ($caseIds as $key => $item) {
            if (!is_numeric($item)) {
                unset($caseIds[$key]);
            }
        }

        if (empty($caseIds)) {
            return 0;
        }

        $var = array();
        $this->arrValueToKey($caseIds);
        $placeTag = $this->arrAppand($var, $caseIds);
        if ($placeTag == "") {
            return 0;
        }

        $sql = 'SELECT count(1) as count FROM ' . $this->tablename . ' LEFT JOIN CustomerSub ON SCase.subid=CustomerSub.subid 
        WHERE caseid IN(' . $placeTag . ')';

        $result = Db::selectOne($sql, $var);
        return $result['count'];
    }


    /**
     * 根据subId获取已推荐职位列表
     * @param $subId
     * @param $field
     * @return array
     */
    public function getCaseListBySubID($subId, $field = '', $rowFrom = 0, $rowTo = 0, $orderBy = '') {
        if (empty($subId)) {
            return null;
        }

        $var = array($subId);

        $field = $field ?: ' SCase.*,CustomerSub.subname ';
        $sql = 'SELECT ' . $field . ' FROM ' . $this->tablename . ' LEFT JOIN CustomerSub ON SCase.subid=CustomerSub.subid 
        WHERE SCase.subid =? and RecmomendDate is not null';

        $sql .= empty($orderBy) ? ' order by RecmomendDate desc,caseid desc' : (' ORDER BY ' . $orderBy);

        return Db::select($sql, $var, $rowFrom, $rowTo);
    }

    /**
     * 根据subId获取职位列表总数
     * @param $subId
     * @return count
     */
    public function getCaseListCountBySubID($subId) {
        if (empty($subId)) {
            return 0;
        }
        $var = array($subId);

        $field = ' count(1) as count ';

        $result = $this->getCaseListBySubID($subId, $field);
        if (empty($result) || !isset($result[0]['count'])) {
            return 0;
        }

        return $result[0]['count'];
    }

    /**
     * 根据项目id获取所有职位数据
     * @param $oprId
     * @param $projectId
     * @param string $field
     * @param string $caseStatus
     * @param array $caseIds
     * @return array
     */
    public function getCaseListWithProjectId($field = '', $caseStatus = 'unfinish', array $caseIds = []) {


        if (empty($field)) {
            $field = 'a.caseid,a.casename,a.projectid,a.subid,a.status,a.hascontact,a.haschargeway';
        } else {
            $fieldArr = explode(',', $field);
            for ($i = 0; $i < count($fieldArr); $i++) {
                $fieldArr[$i] = 'a.' . trim($fieldArr[$i]);
            }
            $field = implode($fieldArr, ',');
        }
        $sql = 'SELECT ' . $field . ' from SCase as a where 1=1 ';
        $var = [];
        if ($caseStatus == 'all') {

        } elseif ($caseStatus == 'active') {
            $sql .= ' and a.status=?';
            $var[] = '01';
        } elseif ($caseStatus == 'finish') {
            $sql .= ' and a.status=?';
            $var[] = '03';
        } else {
            $sql .= ' and a.status<>?';
            $var[] = '03';
        }
        if (!empty($caseIds)) {
            $sql .= ' AND a.caseid IN(' . substr(str_repeat('?,', count($caseIds)), 0, -1) . ')';
            $var = array_merge($var, $caseIds);
        }

        $caseList = Db::select($sql, $var, 0, 1000);
        return $caseList;
    }

    /**
     * 根据hruid获取subid
     * @param $hruid
     * @param string $field
     * @param string $groupBy
     * @param string $orderBy
     * @param int $rowFrom
     * @param int $rowTo
     * @return array|null
     */
    public function getSubList($hruid, $field = '', $groupBy = '', $orderBy = '', $rowFrom = 0, $rowTo = 1000) {
        if (empty($hruid)) {
            return null;
        }

        $var = array($hruid, '01');

        $field = $field ?: 'a.id as accountid,a.subid,b.subname,b.subshowname,b.crmcustomername';

        $sql = "SELECT " . $field . " FROM CustomerAccount a LEFT JOIN CustomerSub b ON a.subid = b.subid 
         WHERE a.ehireaccid = ? AND a.status in ( ?) ";

        $sql .= empty($groupBy) ? '' : ' GROUP BY ' . $groupBy;

        $sql .= empty($orderBy) ? '' : ' ORDER BY ' . $orderBy;

        return Db::select($sql, $var, $rowFrom, $rowTo);
    }

    /**
     * 获取联系人能操作的职位
     * @param string $where
     * @param string $field
     * @param string $groupBy
     * @param string $orderBy
     * @param int $rowFrom
     * @param int $rowTo
     * @return array|null
     */
    public function getCaseInfo($field = '', array $search = [], $rowFrom = 0, $rowTo = 1000) {
        $field = $field ?: 'a.casename,a.caseid,a.subid';
        $sql = "SELECT " . $field . " FROM CaseContacter a LEFT JOIN SCase  b on a.caseid = b.caseid ";
        $var = [];
        $where[] = ' a.status = ? ';
        $var[] = '01';
        if (isset($search['accountid']) && !empty($search['accountid'])) {
            $inFlag = substr(str_repeat('? ,', (count($search['accountid']))), 0, -1);
            $where[] = 'a.accountid in ( ' . $inFlag . ' )';
            $var = array_merge($var, $search['accountid']);
        }

        if (isset($search['status']) && !empty($search['status'])) {
            $inFlag = substr(str_repeat('? ,', (count($search['status']))), 0, -1);
            $where[] = 'b.status in ( ' . $inFlag . ' )';
            $var = array_merge($var, $search['status']);
        }

        $sql .= empty($where) ? '' : ' WHERE ' . implode(' AND ', $where);
        return Db::select($sql, $var, $rowFrom, $rowTo);
    }

    /**
     * 获取流程和流程下的数目
     * @param array $searchParams
     * @param array $groups
     * @return array
     * @throws \Exception
     */
    public function getFlowatCount(array $searchParams, array $groups = []) {
        try {
            $keyName = "flowatcount:subid" . $searchParams['subid'] . ":caseid" . $searchParams['caseid'];
            $redisClient = Redis::connect('customers');
            //首先先查缓存缓存里没有就去查es
            $countDataByEs = $this->groupCountByEs($searchParams, $groups);
            if ($countDataByEs['eserror'] !== 1 && !empty($countDataByEs['aggregations'])) {
                $aggregations = EsSearch::getInstance()->parseCountAgg($countDataByEs['aggregations']);
                $countData = [];
                //redis缓存es查询数据
                foreach ($aggregations as $flowat => $count) {
                    $countData[$flowat] = $count;
                }
                unset($aggregations);
            }

            //获取项目下的流程code
            $projectIdData = $this->getProjectIdByCaseId($searchParams['caseid']);
            if (!isset($projectIdData['projectid']) || empty($projectIdData['projectid'])) {
                throw new RuntimeException('职位projectId为空！');
            }
            $projectId = $projectIdData['projectid'];
            $caseFlowModel = new CaseFlow();
            $flowListStr = $caseFlowModel->getProjectFlowCode($projectId);
            if (empty($flowListStr)) {
                throw new RuntimeException('项目流程为空！');
            }
            $flowListArr = explode(',', $flowListStr);

            //翻译flowat和获取二级流程下的节点
            $caseFlowList = config('app.global_caseflow');
            if (!is_file($caseFlowList)) {
                throw new RuntimeException('职位流程未定义');
            }
            $caseFlow = include $caseFlowList;
            //获取总数
            $returnData = [];
            //获取隐藏的流程
            $unShowFlowatList = (new CaseResumeModel())->getUnShowFloat(2);
            foreach ($flowListArr as $key => $value) {
                $tmp = [];
                $tmp['flowat'] = $value;
                $tmp['count'] = isset($countData[$value]) ? $countData[$value] : 0;
                if (array_key_exists($value, $caseFlow)) {
                    $tmp['flowatName'] = $caseFlow[$value]['name'];
                    //做隐藏字段处理
                    if (array_key_exists($value, $unShowFlowatList)) {
                        $unShowFlowatStatus = isset($unShowFlowatList[$value]['child']) ? array_keys($unShowFlowatList[$value]['child']) : [];
                        $flowatStatus = array_keys($caseFlow[$value]['child']);
                        $unShowFlowat = array_intersect($unShowFlowatStatus, $flowatStatus);
                        foreach ($unShowFlowat as $item) {
                            unset($caseFlow[$value]['child'][$item]);
                        }
                    }
                    $tmp['child'] = $caseFlow[$value]['child'];
                }
                if (!empty($tmp['child'])) {
                    $returnData[] = $tmp;
                }
            }
            return $returnData;
        } catch (RuntimeException $e) {
            Log::error("获取流程下的数目出错：" . $e->getMessage());
            return [];
        }
    }

    /**
     * 分组统计数据
     * @param array $searchParams
     * @param array $groups
     * @return array
     */
    public function groupCountByEs(array $searchParams, array $groups = []) {
        $condition = [];
        if (!empty($groups)) {
            foreach ($groups as $group) {
                $condition = ['groupByParam' => $group];
            }

        }
        //去除隐藏字段
        $unShowFlowatList = (new CaseResumeModel())->getUnShowFloat(1);
        $esServer = EsSearch::getInstance();
        $esParam = [
            EsSearch::EQUAL => $searchParams,
            EsSearch::NOTEQUAL => $unShowFlowatList
        ];
        $groupData = $esServer->setIndex(EsSearch::ES_INDEX_CASE_EN_RESUME)
            ->setWhere($esParam)
            ->setGroupBy($condition)
            ->setSize(0)
            ->search();
        return $groupData;
    }

    /**
     * 检测subid,caseid和用户是否有关联
     * @param array $subIds
     * @param $subId
     * @param $hrUid
     * @param string $caseId
     * @return bool
     */
    public function checkSubIdByHrUid(array $subIds, $subId, $hrUid = "", $caseId = "") {
        $redisClient = Redis::connect('customers');
        if (in_array($subId, $subIds)) {
            if (!empty($caseId)) {
                $keyNameCase = "customersubidcaseids:hruid" . $hrUid . ":subid" . $subId;
                $caseStatus = $redisClient->sIsMember($keyNameCase, $caseId);
                if (!$caseStatus) {
                    return false;
                }
            }
            return true;
        } else {
            return false;
        }
    }

    /**
     * 根据交易公司获取职位id集合
     * @param $hrUid
     * @param $subId
     * @param array $param
     * @return array|int
     */
    public function getRedisCaseIds($hrUid, $subId) {
        //获取caseid
        $keyName = "customersubidcaseids:hruid" . $hrUid . ":subid" . $subId;
        $redisClient = Redis::connect('customers');
        $exites = $redisClient->exists($keyName);
        if ($exites) {
            $caseIds = $redisClient->sMembers($keyName);
        } else {
            $subCaseList = $this->getSubCaseInfo($hrUid);
            $caseIds = isset($subCaseList['caseids'][$subId]) && !empty($subCaseList['caseids'][$subId]) ? $subCaseList['caseids'][$subId] : [];
        }
        return $caseIds;
    }

    /***
     * 获取进行中的、待面试、待筛选、待入职数据
     * @param $hrUid
     * @param $subId
     */
    public function getCaseCount($hrUid, $subId) {
        $caseData = [
            'casecount' => 0,          //暂停和进行的职位数目
            'screenedcount' => 0,      //待筛选数目
            'interviewedcount' => 0,   //待面试数目
            'employedcount' => 0,      //待入职数目
            'eserror' => ''
        ];
        //获取进行中职位统计
        $caseIds = $this->getRedisCaseIds($hrUid, $subId);
        if (empty($caseIds)) {
            return $caseData;
        }
        $caseData['casecount'] = count($caseIds);

        //组装es查询数据
        $searchEqual['caseid'] = $caseIds;
        $searchEqual['subid'] = $subId;
        $searchEqual['status'] = "01";
        $screenedFlowat = ['0302'];     //待筛选流程code
        $interviewedFlowat = ['0801', '0901', '1001', '1101'];        //待面试流程code
        $employedFlowat = ['1501'];          //待入职流程code
        $searchEqual['flowat_flowatstatus'] = array_merge($screenedFlowat, $interviewedFlowat, $employedFlowat);

        //去除隐藏字段
        $unShowFlowatList = (new CaseResumeModel())->getUnShowFloat(1);
        $flowatStatus = array_intersect($unShowFlowatList['flowat_flowatstatus'], $searchEqual['flowat_flowatstatus']);
        if (!empty($flowatStatus)) {
            $searchEqual['flowat_flowatstatus'] = array_diff($searchEqual['flowat_flowatstatus'], $flowatStatus);
            if (!empty($searchEqual['flowat_flowatstatus'])) {
                sort($searchEqual['flowat_flowatstatus']);
            }
        }

        $searchParam = [
            EsSearch::EQUAL => $searchEqual
        ];
        $groupBy = "group by flowat_flowatstatus desc top:500";
        $esServer = EsSearch::getInstance();
        $countData = $esServer->setIndex(EsSearch::ES_INDEX_CASE_EN_RESUME)
            ->setWhere($searchParam)
            ->setGroupBySql($groupBy)
            ->setSize(0)
            ->search();

        //es查询出错
        if ($countData['eserror'] == 1) {
            $caseData['eserror'] = 1;
            return $caseData;
        }

        if (empty($countData['aggregations'])) {
            return $caseData;
        }
        $countData['aggregations'] = $esServer->parseCountAgg($countData['aggregations']);
        //统计分组查询数据
        foreach ($countData['aggregations'] as $flowat => $count) {
            if (in_array($flowat, $screenedFlowat)) {
                $caseData['screenedcount'] += $count;
            } else if (in_array($flowat, $interviewedFlowat)) {
                $caseData['interviewedcount'] += $count;
            } else if (in_array($flowat, $employedFlowat)) {
                $caseData['employedcount'] += $count;
            }
        }

        return $caseData;
    }

    /**
     * 获取职位联系人
     * @param $caseIds
     * @param string $field
     * @param int $rowFrom
     * @param int $rowTo
     * @return array
     */
    public function getCaseContacts($searchParam, $field = '', $groupBy = '', $rowFrom = 0, $rowTo = 1000) {

        $field = empty($field) ? 'a.projectid,a.oprid,a.ischarger,b.caseid,u.cname,u.mobilephone' : $field;

        $sql = "SELECT " . $field . " FROM ProjectOperator a LEFT JOIN SCase b ON a.projectid=b.projectid LEFT JOIN User u ON a.oprid = u.userid WHERE  b.`status` = ?  AND a.status= ? ";

        $var = ["01", "01"];
        if (isset($searchParam['caseids']) && !empty($searchParam['caseids'])) {
            $inFlag = substr(str_repeat('? ,', (count($searchParam['caseids']))), 0, -1);
            $sql .= 'AND  b.caseid in ( ' . $inFlag . ' )';
            $var = array_merge($var, $searchParam['caseids']);
        }

        if (isset($searchParam['ischarger']) && is_numeric($searchParam['ischarger'])) {
            $sql .= 'AND  a.ischarger = ? ';
            $var[] = $searchParam['ischarger'];
        }

        $sql .= empty($groupBy) ? '' : ' group by ' . $groupBy;

        return Db::select($sql, $var, $rowFrom, $rowTo);

    }

    /**
     * 获取项目id
     * @param $caseId
     */
    public function getProjectIdByCaseId($caseId) {

        $sql = "SELECT projectid from SCase where  caseid = ? ";

        $var = [$caseId];

        return Db::selectOne($sql, $var);
    }

    /**
     * 获取职位状态
     * @param $status
     */
    public function getCaseStatus($status) {
        $statusName = '';
        switch ($status) {
            case '01':
                $statusName = '进行中';
                break;
            case '02':
                $statusName = '暂停';
                break;
            case '03':
                $statusName = '结束';
                break;
        }
        return $statusName;
    }

    /**
     * 清除个人subid和caseid
     * @param $hrUid
     * @param $subIds
     */
    public function removeSubCase($hrUid, $subIds) {
        $redisClient = Redis::connect('customers');
        //用来做标识验证subid是否和用户id关联
        foreach ($subIds as $subId) {
            $keyName = "customersubidcaseids:hruid" . $hrUid . ":subid" . $subId;
            $redisClient->del($keyName);
        }
    }

}